"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

exports.default = function (results) {
  var output = invalidOptionsFormatter(results);
  output += deprecationsFormatter(results);

  output = results.reduce(function (output, result) {
    output += formatter(result.warnings, result.source);
    return output;
  }, output);

  // Ensure consistent padding
  output = output.trim();

  if (output !== "") {
    output = "\n" + output + "\n\n";
  }

  return output;
};

var _table = require("table");

var _table2 = _interopRequireDefault(_table);

var _lodash = require("lodash");

var _lodash2 = _interopRequireDefault(_lodash);

var _chalk = require("chalk");

var _chalk2 = _interopRequireDefault(_chalk);

var _path = require("path");

var _path2 = _interopRequireDefault(_path);

var _stringWidth = require("string-width");

var _stringWidth2 = _interopRequireDefault(_stringWidth);

var _logSymbols = require("log-symbols");

var _logSymbols2 = _interopRequireDefault(_logSymbols);

var _util = require("postcss-reporter/lib/util");

var _util2 = _interopRequireDefault(_util);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

var MARGIN_WIDTHS = 9;

var levelColors = {
  info: "blue",
  warning: "yellow",
  error: "red"
};

function deprecationsFormatter(results) {
  var allDeprecationWarnings = _lodash2.default.flatMap(results, "deprecations");
  var uniqueDeprecationWarnings = _lodash2.default.uniqBy(allDeprecationWarnings, "text");

  if (!uniqueDeprecationWarnings || !uniqueDeprecationWarnings.length) {
    return "";
  }

  return uniqueDeprecationWarnings.reduce(function (output, warning) {
    output += _chalk2.default.yellow("Deprecation Warning: ");
    output += warning.text;
    if (warning.reference) {
      output += _chalk2.default.dim(" See: ");
      output += _chalk2.default.dim.underline(warning.reference);
    }
    return output + "\n";
  }, "\n");
}

function invalidOptionsFormatter(results) {
  var allInvalidOptionWarnings = _lodash2.default.flatMap(results, function (r) {
    return r.invalidOptionWarnings.map(function (w) {
      return w.text;
    });
  });
  var uniqueInvalidOptionWarnings = _lodash2.default.uniq(allInvalidOptionWarnings);

  return uniqueInvalidOptionWarnings.reduce(function (output, warning) {
    output += _chalk2.default.red("Invalid Option: ");
    output += warning;
    return output + "\n";
  }, "\n");
}

function logFrom(fromValue) {
  if (fromValue.charAt(0) === "<") return fromValue;
  return _path2.default.relative(process.cwd(), fromValue).split(_path2.default.sep).join("/");
}

function getMessageWidth(columnWidths) {
  if (!process.stdout.isTTY) {
    return columnWidths[3];
  }

  var availableWidth = process.stdout.columns < 80 ? 80 : process.stdout.columns;
  var fullWidth = _lodash2.default.sum(_lodash2.default.values(columnWidths));

  // If there is no reason to wrap the text, we won't align the last column to the right
  if (availableWidth > fullWidth + MARGIN_WIDTHS) {
    return columnWidths[3];
  }

  return availableWidth - (fullWidth - columnWidths[3] + MARGIN_WIDTHS);
}

function formatter(messages, source) {
  if (!messages.length) return "";

  var orderedMessages = _lodash2.default.sortBy(messages, function (m) {
    return m.line ? 2 : 1;
  }, // positionless first
  function (m) {
    return m.line;
  }, function (m) {
    return m.column;
  });

  // Create a list of column widths, needed to calculate
  // the size of the message column and if needed wrap it.
  var columnWidths = { 0: 1, 1: 1, 2: 1, 3: 1, 4: 1 };

  var calculateWidths = function calculateWidths(columns) {
    _lodash2.default.forOwn(columns, function (value, key) {
      var normalisedValue = value ? value.toString() : value;
      columnWidths[key] = Math.max(columnWidths[key], (0, _stringWidth2.default)(normalisedValue));
    });

    return columns;
  };

  var output = "\n";

  if (source) {
    output += _chalk2.default.underline(logFrom(source)) + "\n";
  }

  var cleanedMessages = orderedMessages.map(function (message) {
    var location = _util2.default.getLocation(message);
    var severity = message.severity;
    var row = [location.line || "", location.column || "", _logSymbols2.default[severity] ? _chalk2.default[levelColors[severity]](_logSymbols2.default[severity]) : severity, message.text
    // Remove all control characters (newline, tab and etc)
    .replace(/[\x01-\x1A]+/g, " ") // eslint-disable-line
    .replace(/\.$/, "").replace(new RegExp(_lodash2.default.escapeRegExp("(" + message.rule + ")") + "$"), ""), _chalk2.default.dim(message.rule || "")];

    calculateWidths(row);

    return row;
  });

  output += (0, _table2.default)(cleanedMessages, {
    border: (0, _table.getBorderCharacters)("void"),
    columns: {
      0: { alignment: "right", width: columnWidths[0], paddingRight: 0 },
      1: { alignment: "left", width: columnWidths[1] },
      2: { alignment: "center", width: columnWidths[2] },
      3: { alignment: "left", width: getMessageWidth(columnWidths), wrapWord: true },
      4: { alignment: "left", width: columnWidths[4], paddingRight: 0 }
    },
    drawHorizontalLine: function drawHorizontalLine() {
      return false;
    }
  }).split("\n").map(function (el) {
    return el.replace(/(\d+)\s+(\d+)/, function (m, p1, p2) {
      return _chalk2.default.dim(p1 + ":" + p2);
    });
  }).join("\n");

  return output;
}